#include "./include/basictype.h"
#include "./include/uartconfig.h"

#include <math.h>

BOOL32 UartConfig__isBaudrateSupported(UINT32 baudRate){
    static UINT32 supportedBaudrate[]={9600,14400,19200,38400,57600,115200};
    BOOL32 isBaudrateOk=FALSE;
    
    for(INT32 i=0;i<ARRAY_SIZE(supportedBaudrate);i++){
        if(supportedBaudrate[i]==baudRate)
            return TRUE;
    }
    return FALSE;
}

BOOL32 UartConfig__isDatabitSupported(UINT32 dataBit){
    if(dataBit<UART_DATABIT_COUNT)
        return TRUE;
    return FALSE;
}

BOOL32 UartConfig__isStopbitSupported(UINT32 stopBit){
    if(stopBit<UART_STOPBIT_COUNT)
        return TRUE;
    return FALSE;
}

BOOL32 UartConfig__isParitySupported(UINT32 parity){
    if(parity < UART_PARITY_COUNT)
        return TRUE;
    return FALSE;
}

void * UartConfig_Init(UartConfig_t *pConfig,UINT32 baudRate,UINT8 dataBit,UINT8 stopBit,UINT8 parity){
    SYS_ASSERT(pConfig!=NULL);
  
    if(!UartConfig__isBaudrateSupported(baudRate))
        return NULL;

    if(!UartConfig__isDatabitSupported(stopBit)) 
        return NULL;

    if(!UartConfig__isStopbitSupported(stopBit))
        return NULL;
    
    if(!UartConfig__isStopbitSupported(parity))
        return NULL;

    pConfig->baudRate = baudRate;
    pConfig->dataBit = dataBit;
    pConfig->stopBit = stopBit;
    pConfig->parity = parity;

    return (void *)pConfig;
}


BOOL32 UartConfig_CheckFrameError(UartConfig_t *pConfig,UINT32 uartClk){
    SYS_ASSERT(pConfig!=NULL);

    UINT32 frameBit=(pConfig->dataBit+5)+(pConfig->stopBit+1)+1;

    INT32 udivValue=(INT32)(uartClk/pConfig->baudRate)-1;

    double tUPCLK=((udivValue+1)*16*frameBit+0.0)/(uartClk+0.0);
    double tUEXACT=(frameBit+0.0)/(pConfig->baudRate+0.0);
    double err = 160*fabs(tUPCLK-tUEXACT)/tUEXACT;
    if(err<3)
        return TRUE;
    return FALSE;
}